package br.com.chat.server;

import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import br.com.chat.server.rmi.impl.ChatManagerImpl;
import br.com.chat.server.rmi.impl.MessageReceiverImpl;
import br.com.chat.server.rmi.impl.MessageSenderImpl;


public class RegistryLoader {
    
    private List<Class<?>> types;
    private Registry registry;
    
    public RegistryLoader() {
        super();
        
        types = new ArrayList<Class<?>>();
        
        types.add(MessageReceiverImpl.class);
        types.add(MessageSenderImpl.class);
    }

    public RegistryLoader loadRegistry(){
        try {
            registry = LocateRegistry.createRegistry(1209);
            
            registry.bind("manager", ChatManagerImpl.getInstance());
        } catch (RemoteException e) {
            throw new RuntimeException("create registry fails", e);
        } catch (AlreadyBoundException e) {
            try {
                registry.unbind("manager");
                registry.bind("manager", ChatManagerImpl.getInstance());
            } catch (Exception e1) {
            }
        }
        
        return this;
    }
    
    public void registry(){
        if ( registry == null ){
            return;
        }
        
        ArrayList<String> bounded = null;
        
        for (Class<?> type : types) {
            System.out.println("try load: " + type.getName() );
            
            RemoteImpl annotation = type.getAnnotation(RemoteImpl.class);
            
            try {
                if ( bounded == null ){
                    bounded = new ArrayList<String>(Arrays.asList(registry.list()));
                }
                
                if ( bounded.contains(annotation.value())){
                    System.out.println("unbounding: " + annotation.value() + "..." );
                    registry.unbind(annotation.value());
                }
                
                registry.bind(annotation.value(), (Remote) type.newInstance());
                
                System.out.println("loaded: " + type.getName() + " as " + annotation.value() + " successfuly..." );
            } catch (Exception e) {
                throw new RuntimeException("registry remote objects fail", e);
            }
        }
    }

}
